package com.efivestar.idm.api.service.lock.protocol.handler;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.efivestar.idm.api.common.Cons;
import com.efivestar.idm.api.domain.CameraDomain;
import com.efivestar.idm.api.domain.EventDomain;
import com.efivestar.idm.api.domain.WeixinJoinDeviceDomain;
import com.efivestar.idm.api.exception.ErrorParamException;
import com.efivestar.idm.api.repository.CameraMapper;
import com.efivestar.idm.api.repository.EventMapper;
import com.efivestar.idm.api.repository.WeixinJoinDeviceMapper;
import com.efivestar.idm.api.service.DeviceService;
import com.efivestar.idm.api.service.dto.PowerDto;
import com.efivestar.idm.api.util.ByteUtils;
import com.efivestar.idm.api.util.weixin.WeixinApi;
import com.efivestar.idm.api.util.weixin.bean.TemplateMessage;

import io.netty.buffer.ByteBuf;
import tk.mybatis.mapper.entity.Example;

@Service
public class WarningLockProtocolHandler extends AbstractLockProtocolHandler{

    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private EventMapper mapper;


    @Autowired
    private DeviceService deviceService;

    @Autowired
    private WeixinJoinDeviceMapper userJoinMapper;

    @Autowired
    private CameraMapper cameraMapper;

    @Autowired
    private WeixinApi weixinApi;

    @Value("${weixin.warningTemplateId:jZt8KiYA6wsIkVqNqL12GAfVnzZftFD895bEva0zPLA}")
    private String warningWeixinTemplateId;

    @Value("${service.domain:51ai.cc}")
    private String domain;



    /**
     * @param buf
     * @param lockId
     * @return
     */
    @Override
    public byte[] handleData(ByteBuf buf, String lockId) {
        int length = buf.readableBytes();
        //跳过指令码，不读取
        buf.skipBytes(1);
//        读取电量字节
        byte powerBt = buf.readByte();
        PowerDto power = ByteUtils.getPower(powerBt);
//        读取开门类型字节
        byte eventType = buf.readByte();
        //读取imei(设备编号)
        // String lockId = String.valueOf(buf.readCharSequence(length - 3, Charset.forName("utf-8")));
        //设置设备的电量和更新时间
        deviceService.updatePower(lockId, power.getPowerPercent());
        int eventTypeIntValue = getEventType(eventType);
        EventDomain event = EventDomain.builder().deviceId(lockId).eventType(Cons.WARNING_EVENT_TPE).subEventType(eventTypeIntValue).createTime(new Date()).build();
        mapper.insert(event);
        String warningMesage = "";
        switch (eventTypeIntValue) {
            case Cons.INTELLIGENT_LOG_LEVER_EVENT:
                warningMesage = "智能锁被撬";
                break;
            case Cons.FORCE_DOOR_EVENT:
                warningMesage = "强行开门";
                break;
            case Cons.FIGURE_FAILURE_LOCKED_EVENT:
                warningMesage = "指纹开锁被冻结";
                break;
            case Cons.PASSWORD_FAILURE_LOCKED_EVENT:
                warningMesage = "密码开锁被冻结";
                break;
            case Cons.CARD_FAILURE_LOCKED_EVENT:
                warningMesage = "卡开锁被冻结";
                break;
            case Cons.KEY_FAILURE_LOCKED_EVENT:
                warningMesage = "钥匙开锁被冻结";
                break;
            case Cons.REMOTE_CONTROL_FAILURE_LOCKED_EVENT:
                warningMesage = "遥控开锁被冻结";
                break;
            case Cons.LOW_POWER_EVENT:
                warningMesage = "低电量电压";
                break;
        }
        sendNotification(lockId, eventTypeIntValue, warningMesage);


        return ByteUtils.hexToBytes("00");
    }

    private void sendNotification(String deviceId, int eventTypeIntValue, String warningMesage) {
        //发送微信通知.
        String now = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
        List<WeixinJoinDeviceDomain> weixinJoinDeviceDomains = userJoinMapper.selectByExample(generateUserJoinDeviceExample(deviceId));
        for (WeixinJoinDeviceDomain weixinJoinDeviceDomain : weixinJoinDeviceDomains) {
            String toUser = weixinJoinDeviceDomain.getOpenId();
            Map map = new HashMap<>();
            map.put("first", TemplateMessage.builder().value("您的锁有新的报警信息").color("#F00").build());
            map.put("keyword1", TemplateMessage.builder().value(warningMesage).color("#F00").build());
            map.put("keyword2", TemplateMessage.builder().value(now).color("#F00").build());
            if (eventTypeIntValue != Cons.LOW_POWER_EVENT) {//低电量事件，不需要点开详情,其他的需要

                String cameraUrl = null;
                if (StringUtils.isNotEmpty(weixinJoinDeviceDomain.getCameraId())) {
                    CameraDomain cameraDomain = CameraDomain.builder().cameraId(weixinJoinDeviceDomain.getCameraId()).build();
                    CameraDomain dbCamera = cameraMapper.selectByPrimaryKey(cameraDomain);
                    if (dbCamera != null && StringUtils.isNotEmpty(dbCamera.getUrl())) {
                        cameraUrl = "http://" + domain + "/cameraPage";
                        map.put("remark", TemplateMessage.builder().value("点击查看摄像头").color("#F00").build());
                    } else {
                        logger.error("摄像头:{},不存在对应的视频连接。", weixinJoinDeviceDomain.getCameraId());
                    }
                }
                logger.info("推送的地址为:{}", cameraUrl);
                boolean result = weixinApi.sendTemplateMessage(toUser, warningWeixinTemplateId, cameraUrl,
                        map, null);
            } else {
                boolean result = weixinApi.sendTemplateMessage(toUser, warningWeixinTemplateId, null,
                        map, null);
            }
        }
    }

    @Override
    protected int getDataLenthWithoutDeviceId() {
        return 3;
    }


    private Example generateUserJoinDeviceExample(String deviceId) {
        Example example = new Example(WeixinJoinDeviceDomain.class);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotEmpty(deviceId)){
            criteria.andEqualTo("deviceId", deviceId);
        }
        return example;
    }



    /**
     * 获取开门的子事件类型.
     * @param eventTypeBt
     * @return
     */
    private int getEventType(byte eventTypeBt) {
        String eventType = ByteUtils.bytes2hex(eventTypeBt);
        switch (eventType) {
            case "00":
                return Cons.INTELLIGENT_LOG_LEVER_EVENT;
            case "01":
                return Cons.FORCE_DOOR_EVENT;
            case "02":
                return Cons.FIGURE_FAILURE_LOCKED_EVENT;
            case "03":
                return Cons.PASSWORD_FAILURE_LOCKED_EVENT;
            case "04":
                return Cons.CARD_FAILURE_LOCKED_EVENT;
            case "05":
                return Cons.KEY_FAILURE_LOCKED_EVENT;
            case "06":
                return Cons.REMOTE_CONTROL_FAILURE_LOCKED_EVENT;
            case "07":
                return Cons.LOW_POWER_EVENT;
        }
        throw new ErrorParamException();
    }



    public static byte[] subBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        System.arraycopy(src, begin, bs, 0, count);
        return bs;
    }

    @Override
    public String udpHead(){
        return Cons.UDP_HEAD_EF01;
    }

    @Override
    public String udpCommand(){
        return Cons.UDP_COMMAND_WARNING;
    }





}






